package server.lunch;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import com.zaxxer.hikari.HikariPoolMXBean;
import com.zaxxer.hikari.pool.HikariPool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
import org.springframework.boot.jdbc.metadata.HikariDataSourcePoolMetadata;
import org.springframework.context.ApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.config.TransactionManagementConfigUtils;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.DefaultTransactionStatus;
import server.entity.Student;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import javax.sql.PooledConnection;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @ClassName AppLucnh
 * @Description
 * @Author Jingxiao.Ye
 * @Date 2021/12/6 上午12:47
 * @Version V1.0
 * @Since JDK 11
 */
@Component
public class AppLunch implements ApplicationRunner {

    @Autowired
    private HikariDataSource hikariDataSource;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        HikariPool hikariPool = new HikariPool(hikariDataSource);
//        1）使用 JDBC 原生接口，实现数据库的增删改查操作。
//        2）使用事务，PrepareStatement 方式，批处理方式，改进上述操作。
//        3）配置 Hikari 连接池，改进上述操作。提交代码到 GitHub。
        Connection connection = hikariPool.getConnection();
        PreparedStatement preparedStatement = connection.prepareStatement("select *from student");
        preparedStatement.executeUpdate("INSERT INTO `study`.`student`(`id`, `name`) VALUES (null, 'a');");
        preparedStatement.executeUpdate("UPDATE `study`.`student` SET `name` = 'b' WHERE `id` = 1;");
        ResultSet resultSet = preparedStatement.executeQuery("select *from student");
        while (resultSet.next()){
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            Student student = new Student();
            student.setId(id);
            student.setName(name);
        }
        preparedStatement.executeUpdate("DELETE FROM `study`.`student` WHERE `id` = 1;");
        List<Student> students = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Student student = new Student();
            student.setName(UUID.randomUUID().toString());
            students.add(student);
        }
        connection.close();

        commit(hikariPool,students);
    }

    public void commit(HikariPool hikariPool, List<Student> students) throws SQLException {
        Connection connection = hikariPool.getConnection();
        connection.setAutoCommit(false);
        try {
            students.parallelStream().forEach(s->{
                try {
                    PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO `study`.`student`(`id`, `name`) VALUES (null, ?);");
                    preparedStatement.setString(1,s.getName());
                    preparedStatement.executeUpdate();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                    throw new RuntimeException("sql Exception");
                }
            });
            connection.commit();
        } catch (Exception e) {
            e.printStackTrace();
            connection.rollback();
        }
    }
}
